package com.heima.wemedia.service.impl;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.apis.schedule.IScheduleClient;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.schedule.dto.Task;
import com.heima.model.wemedia.dtos.WmNewsDto;
import com.heima.model.wemedia.dtos.WmNewsPageReqDto;
import com.heima.model.wemedia.pojos.WmMaterial;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmNewsMaterial;
import com.heima.utils.ProtostuffUtil;
import com.heima.wemedia.mapper.WmMaterialMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmNewsMaterialMapper;
import com.heima.wemedia.service.AutoScanService;
import com.heima.wemedia.service.WmNewsService;
import com.heima.wemedia.thread.USerThreadLocal;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;

@Service
@Slf4j
@Transactional
public class WmNewsServiceImpl  extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {
@Autowired
private WmNewsMapper wmNewsMapper;
@Autowired
private WmMaterialMapper wmMaterialMapper;
@Autowired
private AutoScanService autoScanService;

@Autowired
private WmNewsMaterialMapper wmNewsMaterialMapper;
    //频道列表
    @Override
    public PageResponseResult newsList(WmNewsPageReqDto dto) {
        //在编写前进行判断传入的值是否为空，
if (dto==null){
    return new PageResponseResult(0,0,0);
}
  //1构建查询条件
        Short status = dto.getStatus();
        Date beginPubDate = dto.getBeginPubDate();
        Date endPubDate = dto.getEndPubDate();
        Integer channelId = dto.getChannelId();
        String keyword = dto.getKeyword();
        Integer page1 = dto.getPage();
        Integer size = dto.getSize();
        LambdaQueryWrapper<WmNews> wrapper = new LambdaQueryWrapper<>();
        //这个判断是构造器的特性  状态查询
        wrapper.eq(status!=null,WmNews::getStatus,status);
  //发布的查询条件 范围查询between
        wrapper.between(beginPubDate!=null &&endPubDate!=null, WmNews::getPublishTime,beginPubDate,endPubDate);

        //频道查询
        wrapper.eq(channelId!=null, WmNews::getChannelId,channelId);

        //对关键字进行查询 模糊查询
        wrapper.like(StringUtils.isNotEmpty(keyword), WmNews::getTitle,keyword);
        //查询用户信息
        wrapper.eq(WmNews::getUserId, USerThreadLocal.get().getId());

        //2根据时间进行排序
        wrapper.orderByDesc(WmNews::getPublishTime);

        //3构建分页条件
        Page<WmNews> page = new Page<>(page1, size);

        //4执行分页条件
        Page<WmNews> wmNewsPageResult = wmNewsMapper.selectPage(page, wrapper);


        //5
        Long total = wmNewsPageResult.getTotal();
        //页码 每页条数 总条数
        PageResponseResult responseResult=new PageResponseResult(page1,size,total.intValue());
responseResult.setData(wmNewsPageResult.getRecords());

        //5构建返回值

        return responseResult;
    }


    //新闻发布
    @Autowired
    private IScheduleClient iScheduleClient;
        @Override
        @Transactional(rollbackFor = RuntimeException.class)
        public ResponseResult submit(WmNewsDto dto) {

   //1获取新闻内容
                WmNews wmNews = wmNewsDto2WmNews(dto);
                if (wmNews!=null){
                        return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
                }

                //2插入新闻
                int insert = wmNewsMapper.insert(wmNews);
                if (insert<1){  //判断是否插入成功
                        return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR);
                }

                //3判断是不是草稿
                Short status = dto.getStatus();
                if (status==0){
                    log.info("文章为草稿，所以没有添加素材");
                        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
                }

                //4获取新闻图片
                String content = dto.getContent();
                List<String> contentImages = getContentImages(content);

                //5如果是自动布局，要到内容图中提取，并返回封面图
                List<String> images = dto.getImages();
                Short type = dto.getType();
                //类型 图片 文章内容
                List<String> coverImages = getCoverImages(type, images, contentImages);

                //6素材添加
                Boolean contentImageResult = addMaterial(wmNews.getId(), contentImages, 0);
       if (!contentImageResult){
        throw new RuntimeException("素材内容添加失败");
                }

                //7 素材和新闻关系添加
                Boolean coverImageResult = addMaterial(wmNews.getId(), coverImages, 1);
       if (!coverImageResult){
                        throw new RuntimeException("封面添加失败");
                }
       //8调用审核代码
//            try {
////                autoScanService.autoScanWmNews(wmNews.getId().longValue());
////            } catch (Exception e) {
////                e.printStackTrace();
////            }
            Boolean addToTask = addToTask(wmNews.getId(), wmNews.getPublishTime().getTime());
       //判断如果不成功则抛出异常
            if (!addToTask){
                throw new RuntimeException("任务添加失败");
            }
            return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
        }
//上下架新闻
@Autowired
private KafkaTemplate kafkaTemplate;
    @Override
    public ResponseResult downOrUp(WmNewsDto wmNewsDto) {
            //1先参数判空
            if (wmNewsDto==null){
                return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
            }
            //2.查询新闻
        Integer id = wmNewsDto.getId();
        WmNews wmNews = wmNewsMapper.selectById(id);
        if (wmNews==null){
            log.warn("新闻不存在");
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,"新闻不存在");
        }
        //3.检查状态是否为发布
        Short status = wmNews.getStatus();
        if (status!=9){
            log.warn("新闻未上架");
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"新闻未上架");
        }
        //4.修改新闻enable字段
        //新闻先获得enable
        Short enable = wmNewsDto.getEnable();
        wmNews.setEnable(enable);
        int i = wmNewsMapper.updateById(wmNews);
        if (i<1){
            log.warn("新闻更新失败");
            return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR,"新闻更新失败");

        }
        HashMap<String, Object> map = new HashMap<>();
        map.put("articleId",wmNews.getId());
        map.put("enable",wmNews.getEnable());
        kafkaTemplate.send("down_or_up",JSON.toJSONString(map));


        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    public ResponseResult findAll(WmNewsPageReqDto dto) {
        if(dto == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }

        Short status = dto.getStatus();
        String keyword = dto.getKeyword();
        Integer channelId = dto.getChannelId();
        Date endPubDate = dto.getEndPubDate();
        Date beginPubDate = dto.getBeginPubDate();

        Integer size = dto.getSize();
        Integer pageNum = dto.getPage();

        // 查询频道
        LambdaQueryWrapper<WmNews> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(channelId != null, WmNews::getChannelId, channelId);

        // 查询发布时间范围
        wrapper.between(beginPubDate != null && endPubDate != null,
                WmNews::getPublishTime, beginPubDate, endPubDate);

        // 模糊查找关键词
        wrapper.like(StringUtils.isNotEmpty(keyword), WmNews::getTitle, keyword);

        // 查询状态
        wrapper.eq(status != null, WmNews::getStatus, status);

        // 根据用户查询
        wrapper.eq(WmNews::getUserId, USerThreadLocal.get().getId());

        // 排序
        wrapper.orderByDesc(WmNews::getCreatedTime);

        Page<WmNews> page = new Page<>(pageNum, size);
        Page<WmNews> result = wmNewsMapper.selectPage(page, wrapper);

        // 组装返回值
        Long total = result.getTotal();
        PageResponseResult pageResult = new PageResponseResult(pageNum, size, total.intValue());
        pageResult.setData(result.getRecords());

        return pageResult;
    }



    private  Boolean addToTask(Integer newsId,Long executeTime){
            Task task = new Task();
task.setExecuteTime(executeTime);
            WmNews wmNews = new WmNews();
            wmNews.setId(newsId);
            //序列化器
            task.setParameters(ProtostuffUtil.serialize(wmNews));
            ResponseResult responseResult = iScheduleClient.addTask(task);
            if (responseResult!=null && responseResult.getCode()==200){
return true;
            }
return false;

        }



//wmNewsDto转成WmNews
        public WmNews wmNewsDto2WmNews(WmNewsDto wmNewsDto){

if (wmNewsDto==null){
        return null;
}
            // 把wmNewsDto里的参数与wmNews里的参数进行比对并拷贝
                WmNews wmNews = new WmNews();
                BeanUtils.copyProperties(wmNewsDto,wmNews);

                //处理不相同的字段
                wmNews.setUserId(USerThreadLocal.get().getId());
               //判断图片的类型 单图 多图 无图 或是自动填充图片
                if (wmNewsDto.getType()==-1){
                        wmNews.setType(null);
                }
                wmNews.setCreatedTime(new Date());
                List<String> images = wmNewsDto.getImages();
                if (!CollectionUtils.isEmpty(images)){
                   //把图片集合弄成逗号隔开的字符串    第一个是集合第二个是逗号
                        String join = StringUtils.join(images, ",");
                        wmNews.setImages(join);
                }
                wmNews.setEnable((short)1);
                return wmNews;
        }
        private List<String> getContentImages(String content){
            if (StringUtils.isEmpty(content)){
                    return new ArrayList<>();
            }
                ArrayList<String> arrayList = new ArrayList<>();
                //将content转换成集合
                List<Map> maps = JSON.parseArray(content, Map.class);
            if (CollectionUtils.isEmpty(maps)){
                    return new ArrayList<>();
            }
            //得到集合后进行遍历
                for (Map map : maps) {
                        if (CollectionUtils.isEmpty(map)){
                                continue;
                        }
                        //判断type=image的数据
                        Object type = map.get("type");
                        if ("image".equals(type)) {
                                String value = (String) map.get("value");
                                arrayList.add(value);
                        }

                }
                return arrayList;
        }
        private List<String> getCoverImages(Short type,List<String> images,List<String> contentImages){
          //如果前端传入的只是-1则说明是自动布局
          if (type ==-1){
              //判断图片数量
                  int size = contentImages.size();
                  if (size>=3){
                       return contentImages.subList(0,2);
                  }else if (size ==2){
                          return contentImages.subList(0,1);

                  }else if (size==1){
                          ArrayList<String> strings = new ArrayList<>();
                          strings.add(contentImages.get(0));
                          return strings;
                  }else {
                          return new ArrayList<>();
                  }

          }

return images;

        }
        //添加的那个新闻，图片集合，图片类型
        @Transactional(rollbackFor = RuntimeException.class)
        public Boolean addMaterial(Integer newsId,List<String> imageList, Integer type){
//先判空
                if (CollectionUtils.isEmpty(imageList)){
                        return true;
                }
                for (String s : imageList) {
                        if (StringUtils.isEmpty(s)){
                                continue;
                        }
                        WmMaterial wmMaterial = new WmMaterial();
                        wmMaterial.setUserId(USerThreadLocal.get().getId());
                        wmMaterial.setUrl(s);
                        wmMaterial.setIsCollection((short)0);
                        wmMaterial.setType((short)0);
                        wmMaterial.setCreatedTime(new Date());
                        int insert = wmMaterialMapper.insert(wmMaterial);
                        if (insert<1){
                                throw new RuntimeException("素材添加失败");
                        }

                        WmNewsMaterial newsMaterial = new WmNewsMaterial();
                        newsMaterial.setType(type.shortValue());
                        newsMaterial.setOrd((short)1);
                        newsMaterial.setNewsId(newsId);
                        newsMaterial.setMaterialId(wmMaterial.getId());
                        int insert1 = wmNewsMaterialMapper.insert(newsMaterial);
                        if (insert1<1){
                                throw new RuntimeException("素材关系添加失败");
                        }
                }

return true;
        }
}

